<template>
  <div>
    <el-switch
      style='display: block'
      v-model='readOnly'
      active-color='#13ce66'
      inactive-color='#ff4949'
      active-text='阅读模式'
      inactive-text='编辑模式'
    >
    </el-switch>
    <hr/>
    <el-button type="danger" @click="batchDelete">批量删除</el-button>
    <hr/>
    <!--
      : v-bind的简写
      highlight-current 选中会高光,默认false
      expand-on-click-node 点击node的文字node就会展开,默认true
      data el-tree双向绑定的数据主体
      props 相关配置
      default-expanded-keys 默认展开的node
    -->
    <el-tree
      ref="menuTree"
      show-checkbox
      :highlight-current='true'
      :expand-on-click-node='false'
      :data='categories'
      :props='defaultProps'
      :default-expanded-keys='expandedKey'
      node-key='catId'
    ><span class='custom-tree-node' slot-scope='{ node, data }'>
        <span>{{ node.label }}</span>
        <span v-show='!readOnly'>
          <el-button v-show="data.catLevel<=2" type='text' size='mini' @click='() => append(data)'>
            添加
          </el-button>
          <el-button type='text' size='mini' @click='() => edit(data)'>
            修改
          </el-button>
          <el-button
            v-show='node.childNodes.length === 0'
            type='text'
            size='mini'
            @click='() => remove(node, data)'
          >
            删除
          </el-button>
        </span>
      </span></el-tree
    >
    <el-dialog :title='title' :visible.sync='dialogVisible' width='30%'>
      <el-form :model='category'>
        <el-form-item v-show='category.showForAppend' label='分类名称'>
          <el-input v-model='category.name' autocomplete='off'></el-input>
        </el-form-item>
        <el-form-item v-show='category.showForEdit' label='分类名称'>
          <el-input v-model='category.name' autocomplete='off'></el-input>
        </el-form-item>
        <el-form-item v-show='category.showForEdit' label='图标'>
          <el-input v-model='category.icon' autocomplete='off'></el-input>
        </el-form-item>
        <el-form-item v-show='category.showForEdit' label='计量单位'>
          <el-input
            v-model='category.productUnit'
            autocomplete='off'
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot='footer' class='dialog-footer'>
        <el-button @click='cancelOperation'>取 消</el-button>
        <el-button type='primary' @click='submitData'>确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  data () {
    return {
      // 树是否只读
      readOnly: true,
      // 对话dialog的标题
      title: '默认标题',
      // 对话的类型
      dialogType: '默认对话类型',
      formLabelWidth: '120px',
      category: {
        // 以下是数据库的字段
        name: '',
        parentCid: 0,
        catLevel: 0,
        showStatus: 1,
        sort: 0,
        catId: null,
        icon: null,
        productUnit: null,
        // 以下是用来操控form的动态显示的布尔值
        showForAppend: false,
        showForEdit: false
      },

      // 与tree双向绑定的数据
      categories: [],
      // 与tree双向绑定的数据
      expandedKey: [],
      // 控制对话是否可见的布尔值
      dialogVisible: false,

      // tree的一些配置属性,详见elementUI官方文档
      defaultProps: {
        children: 'children',
        label: 'name'
      }
    }
  },

  // 提示消息,内容与配置项目通过形参输入
  methods: {
    // 批量删除的方法
    batchDelete () {
      // 找出所有被选中的节点
      let checkedNodes = this.$refs.menuTree.getCheckedNodes(false, false)
      // 当选中的节点数量不为零时才可以删除
      if (checkedNodes.length !== 0) {
        let catIds = []
        let names = []
        for (let i = 0; i < checkedNodes.length; i++) {
          catIds.push(checkedNodes[i].catId)
          names.push(checkedNodes[i].name)
        }
        console.log('所有被选中的节点的catId数组 --> ', catIds)
        this.$confirm(`是否批量删除【${names}】`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          // 发删除请求
          this.$http({
            url: this.$http.adornUrl('/product/category/delete'),
            method: 'post',
            data: this.$http.adornData(catIds, false)
          }).then(() => {
            this.showMessage('success', true, '删除成功!')
            // 刷新数据
            this.getMenus()
          })
        }).catch(() => {
          this.showMessage('info', true, '操作取消')
        })
      }
    },

    // 展示消息用的方法
    showMessage (type, isTextCenter, content) {
      this.$message({
        // 消息类型
        type: type,
        // 消息的位子是否居中
        center: isTextCenter,
        // 消息内容
        message: content
      })
    },

    // 点击对话框的确定按钮调用的方法
    submitData () {
      // 根据对话框的目的来调用不同的方法
      if (this.dialogType === 'add') {
        // 执行添加
        this.addCategory()
        // 使name不再回显
        this.category.name = ''
      }
      if (this.dialogType === 'edit') {
        // 执行编辑
        this.editCategory()
      }
    },

    // 执行编辑操作
    editCategory () {
      // 先列出需要提交数据库的字段
      // catId 需要通过此字段来定位数据
      let {catId, name, icon, productUnit} = this.category
      let data = {
        catId: catId,
        name: name,
        icon: icon,
        productUnit: productUnit
      }
      console.log('被编辑的节点的数据 -->', data)
      // 发送请求
      this.$http({
        url: this.$http.adornUrl('/product/category/update'),
        method: 'post',
        data: this.$http.adornData(data, false)
      }).then(() => {
        // 使对话框不可见
        this.dialogVisible = false
        // 提示消息
        this.showMessage('success', true, '修改成功!')
        // 刷新数据
        this.getMenus()
        // 展开父节点(排除没有父节点的节点)
        if (this.category.parentCid !== 0) {
          this.expandedKey = [this.category.parentCid]
        }
      })
    },

    // 执行添加操作
    addCategory () {
      // 列出需要上传数据库的字段
      let {name, parentCid, catLevel, showStatus, sort} = this.category
      let data = {name, parentCid, catLevel, showStatus, sort}
      console.log('被添加的节点的数据 --> ', data)
      // 关闭对话框
      this.dialogVisible = false
      // 发送请求
      this.$http({
        url: this.$http.adornUrl('/product/category/save'),
        method: 'post',
        data: this.$http.adornData(data, false)
      }).then(() => {
        this.showMessage('success', true, '添加成功!')
        // 刷新数据
        this.getMenus()
        // 展开父节点
        this.expandedKey = [this.category.parentCid]
      })
    },

    // 对话框的取消按钮的单击事件
    cancelOperation () {
      // 使对话框不可见
      this.dialogVisible = false
      this.showMessage('info', true, '操作取消')
    },

    // 从数据库获取全部分类数据
    getMenus () {
      this.$http({
        url: this.$http.adornUrl('/product/category/list/tree'),
        method: 'get'
      }).then(({data}) => {
        this.categories = data.categories
      })
    },

    // 添加按钮的单机事件
    append (data) {
      console.log('点击添加按钮传入的数据 --> ', data)
      // 设定对话框的标题
      this.title = '添加分类'
      // 设定对话框的类型
      this.dialogType = 'add'
      // 使对话框可见
      this.dialogVisible = true
      // 调整输入框的可见性
      this.category.showForAppend = true
      this.category.showForEdit = false
      // 给category赋新值(catId:主键自增)
      this.category.parentCid = data.catId
      this.category.showStatus = 1
      this.category.sort = 0
      this.category.catLevel = data.catLevel * 1 + 1
    },

    // 删除按钮的单机事件
    remove (node, data) {
      this.title = '删除分类'
      let ids = [data.catId]
      this.$confirm(`是否删除分类【${data.name}】?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.$http({
            url: this.$http.adornUrl('/product/category/delete'),
            method: 'post',
            data: this.$http.adornData(ids, false)
          }).then(() => {
            this.showMessage('success', true, '删除成功!')
            // 刷新数据
            this.getMenus()
            // 得到被删除的节点的父节点的Id,并展开父节点
            this.expandedKey = [node.parent.data.catId]
          })
        })
        .catch(() => {
          this.showMessage('info', true, '已取消删除')
        })
    },

    // 编辑按钮的单击事件
    edit (data) {
      this.title = '修改分类'
      this.dialogType = 'edit'
      // 调整输入框的可见性
      this.category.showForAppend = false
      this.category.showForEdit = true
      // 使对话框可见
      this.dialogVisible = true
      // 发送请求获取最新数据
      this.$http({
        url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
        method: 'get',
        params: this.$http.adornParams({})
      }).then(({data}) => {
        // 给category赋新值
        this.category.parentCid = data.category.parentCid
        this.category.name = data.category.name
        this.category.catId = data.category.catId
        this.category.icon = data.category.icon
        this.category.productUnit = data.category.productUnit
      })
    }
  },

  // 生命周期-创建时
  created () {
    // 创建时获取全部数据
    this.getMenus()
  }
}
</script>

<style>
</style>
